package bkt.framework.db;

import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import bkt.framework.FrameworkConstants;
import bkt.framework.tool.FrameworkDatabaseUtil;
import bkt.framework.tool.FrameworkMobileUtil;

public class DatabaseManager extends SQLiteOpenHelper {

	private static String DATABASE_PATH = null;
	private static String DATABASE_NAME = null;
	private static String FILE_ABSOLUTE_PATH = null;
	private static Context context = null;
	private static String packageName = null;
	
	
	private static int DATABASE_VERSION = -1;
	
	public static SQLiteDatabase encReadableDB = null;
	public static SQLiteDatabase encWritableDB = null;
	
	public static SQLiteDatabase GetEncReadableDB(){
		if(DatabaseManager.encReadableDB == null){
			DatabaseManager.encReadableDB =  new DatabaseManager(DatabaseManager.context, DatabaseManager.packageName, DatabaseManager.DATABASE_NAME, DatabaseManager.DATABASE_VERSION).getReadableDatabase(null);
		}
		return DatabaseManager.encReadableDB;
	}
	
	private final static FrameworkDatabaseUtil dbUtil = new FrameworkDatabaseUtil();

	
	
	public DatabaseManager(Context _context,String _packageName, String dbName,int dbVersion) {
		super(context, dbName, null, dbVersion);
		DatabaseManager.context = _context;
		DatabaseManager.packageName = _packageName;		
		
		DatabaseManager.DATABASE_NAME = dbName;
		DatabaseManager.DATABASE_PATH = "data/data/"+DatabaseManager.packageName+"/databases/";
		DatabaseManager.FILE_ABSOLUTE_PATH = DatabaseManager.DATABASE_PATH + DatabaseManager.DATABASE_NAME;
		DatabaseManager.DATABASE_VERSION = dbVersion;
		
		DatabaseManager.dbUtil.loadLibraries(DatabaseManager.context);
		
	}

	@Override
	public void onCreate(SQLiteDatabase arg0) {
	}
	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
	}
	
	@Override
	public synchronized SQLiteDatabase getReadableDatabase(String dbKey) {
		String usedKey = TextUtils.isEmpty(dbKey) ? FrameworkMobileUtil.getDeviceDbKey(DatabaseManager.context,DatabaseManager.packageName):dbKey;
		if(DatabaseManager.encReadableDB == null){
			DatabaseManager.encReadableDB = super.getReadableDatabase(usedKey);
		}else if(!DatabaseManager.encReadableDB.isOpen()){
			DatabaseManager.encReadableDB = SQLiteDatabase.openDatabase(DatabaseManager.DATABASE_NAME, usedKey, null, SQLiteDatabase.OPEN_READONLY);
		}
		return DatabaseManager.encReadableDB;
	}
	@Override
	public synchronized SQLiteDatabase getWritableDatabase(String dbKey) {
		String usedKey = TextUtils.isEmpty(dbKey) ? FrameworkMobileUtil.getDeviceDbKey(DatabaseManager.context,DatabaseManager.packageName):dbKey;
		if(DatabaseManager.encWritableDB == null){
			DatabaseManager.encWritableDB = super.getWritableDatabase(usedKey);
		}else if(!DatabaseManager.encWritableDB.isOpen()){
			DatabaseManager.encWritableDB = SQLiteDatabase.openDatabase(DatabaseManager.DATABASE_NAME, usedKey, null, SQLiteDatabase.OPEN_READWRITE);
		}
		return DatabaseManager.encWritableDB;
	}
	
	public synchronized boolean copyDatabase(){
		boolean retVal = false;
		
		if(!DatabaseManager.dbUtil.isDBExist(DatabaseManager.FILE_ABSOLUTE_PATH,FrameworkMobileUtil.getDeviceDbKey(DatabaseManager.context,DatabaseManager.packageName))){
			DatabaseManager.dbUtil.copyDatabaseFile(DatabaseManager.context,DatabaseManager.DATABASE_NAME,DatabaseManager.DATABASE_PATH,DatabaseManager.FILE_ABSOLUTE_PATH);
			SQLiteDatabase encrDB = null;
			try{
				DatabaseManager.dbUtil.loadDecryptedDB(DatabaseManager.context,DatabaseManager.DATABASE_NAME,FrameworkConstants.SQLITE_MASTER_TABLE_NAME,DatabaseManager.DATABASE_VERSION,FrameworkConstants.SQLITE_EXCLUDED_TABLES);
				encrDB = DatabaseManager.dbUtil.encryptDatabase(DatabaseManager.context,DatabaseManager.DATABASE_NAME,FrameworkMobileUtil.getDeviceDbKey(DatabaseManager.context,DatabaseManager.packageName));
				if(encrDB != null){
					DatabaseManager.dbUtil.importData(encrDB,FrameworkMobileUtil.getDeviceDbKey(DatabaseManager.context,DatabaseManager.packageName));
					retVal= true;
				}
			}catch(Exception e){
				Log.e(FrameworkConstants.LOGTAG_FRAMEWORK_DATABASE_MANAGER, "Database Initilization Error",e);
			}finally{
				if(encrDB != null && encrDB.isOpen()){
					try {
						encrDB.close();
						encrDB = null;
					} catch (Exception ex) {
						Log.e(FrameworkConstants.LOGTAG_FRAMEWORK_DATABASE_MANAGER, "Database Close Error",ex);
					}
				}
			}
		}

		return retVal;
	}
	
	public synchronized void startTransaction(){
		if(DatabaseManager.encWritableDB == null){
			DatabaseManager.encWritableDB =  getWritableDatabase(null);
		}
		DatabaseManager.encWritableDB.beginTransaction();
	}
	public synchronized void commitTransaction(){
		if(DatabaseManager.encWritableDB == null){
			DatabaseManager.encWritableDB =  getWritableDatabase(null);
		}
		DatabaseManager.encWritableDB.setTransactionSuccessful();
	}
	public synchronized void endTransaction(){
		if(DatabaseManager.encWritableDB == null){
			DatabaseManager.encWritableDB =  getWritableDatabase(null);
		}
		DatabaseManager.encWritableDB.endTransaction();
	}
}
